﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Net;
using System.Text.RegularExpressions;
using System.Drawing;

namespace SeriesUpdatesCommon
{
    public class StreamPlanetSeries
    {
        /// <summary>
        /// Code source de la page concernant une série
        /// </summary>
        private string _source;

        /// <summary>
        /// Exécute une requête HTTP et récupère la réponse
        /// </summary>
        /// <returns>Stream si la requête a bien été exécutée, NULL sinon</returns>
        private Stream getStream(string url)
        {
            Stream resStream = null;

            try
            {
                var request = (HttpWebRequest)WebRequest.Create(url);
                var response = (HttpWebResponse)request.GetResponse();
                resStream = response.GetResponseStream();
            }
            catch (Exception)
            {
                //MessageBox.Show(@"Un problème a été rencontré lors de la requête : " + e);
                //throw new Exception("Impossible d'exécuter la requête sur le serveur distant : " + e.Message);
            }

            return resStream;
        }

        /// <summary>
        /// Récupère le code source de la page
        /// </summary>
        /// <param name="url">URL de la série</param>
        public void fetchSourceData(string url)
        {
            string pageSource = "";
            
            try
            {
                using (StreamReader sr = new StreamReader(this.getStream(url)))
                {
                    pageSource = sr.ReadToEnd();
                }
            }
            catch (Exception)
            {
                //MessageBox.Show(@"Un problème a été rencontré pour récupérer les données de la série '" + this.name + "' : " + e);
            }

            this._source = pageSource;
        }

        /// <summary>
        /// Récupère la liste de tous les nouveaux épisodes à partir du dernier que l'on a
        /// </summary>
        /// <param name="saison">Saison actuelle</param>
        /// <param name="lastEpisodeNumber">Numéro du dernier épisode possédé</param>
        /// <returns></returns>
        public List<Episode> getEpisodes(string saison, int lastEpisodeNumber)
        {
            List<Episode> newEpisodes = new List<Episode>();

            try
            {
                string[] search = this._source.Split(new string[] { saison + "</h3>" }, StringSplitOptions.None);
                search = search[1].Split(new string[] { "</form>" }, StringSplitOptions.None);
                search = search[0].Split(new string[] { "\">Episode" }, StringSplitOptions.None);

                int currentNumber = 0;

                for (int i = 1; i < search.Length; i++)
                {
                    currentNumber = Convert.ToInt32(Regex.Match(search[i], @"\d+").ToString());

                    if (currentNumber <= lastEpisodeNumber)
                    {
                        continue;
                    }

                    // On récupère le nom du dernier épisode
                    string nameSearch = "Episode " + currentNumber;
                    string[] name = nameSearch.Split(new string[] { "</a>" }, StringSplitOptions.None);

                    // On récupère l'url du dernier épisode
                    string[] urlSearch = search[i - 1].Split(new string[] { "href=\"" }, StringSplitOptions.None);
                    string url = urlSearch[urlSearch.Length - 1];

                    newEpisodes.Add(new Episode(currentNumber, name[0], url));
                }
            }
            catch (Exception)
            {
                //MessageBox.Show(@"Un problème a été rencontré pour récupérer les données de la série '" + this.name + "' : " + exception);
            }

            return newEpisodes;
        }

        /// <summary>
        /// Permet de savoir si la série est terminée ou toujours en cours de production
        /// </summary>
        /// <returns>True ou False</returns>
        public bool isEndedSerie()
        {
            if (this._source.Contains("Serie terminee"))
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// Retourne la prochaine saison (s'il y a)
        /// </summary>
        /// <param name="currentSaison">Saison actuelle</param>
        /// <returns>Nom de la prochaine saison, vide s'il n'y en a pas</returns>
        public string getNextSaison(string currentSaison)
        {
            string resultSaison = "";

            try
            {
                string[] saisonSearch = this._source.Split(new string[] { " rapide : " }, StringSplitOptions.None);
                saisonSearch = saisonSearch[1].Split(new string[] { "</a><div" }, StringSplitOptions.None);

                string[] numSaison = currentSaison.Split(new string[] { "Saison " }, StringSplitOptions.None);
                numSaison = numSaison[1].Split(new string[] { " (" }, StringSplitOptions.None);

                int bSaison = Convert.ToInt32(numSaison[0]);
                string aSaison = (bSaison + 1).ToString("D2");

                if (saisonSearch[0].Contains("Saison " + aSaison + " (VOSTFR)"))
                {
                    resultSaison = "Saison " + aSaison + " (VOSTFR)";
                }
            }
            catch (Exception)
            {
                //MessageBox.Show(@"Un problème a été rencontré pour récupérer les données de la série '" + this.name + "' : " + e);
            }

            return resultSaison;
        }

        /// <summary>
        /// Télécharge l'image de la série
        /// </summary>
        /// <param name="imagePath">Path complet du fichier à créer</param>
        /// <returns>True si bien créé, False sinon</returns>
        public bool downloadPicture(string imagePath)
        {
            try
            {
                Image image;
                string fileUrl = "";

                string[] search = this._source.Split(new string[] { "arrondi fiche" }, StringSplitOptions.None);
                search = search[1].Split(new string[] { "<img src=\"" }, StringSplitOptions.None);
                search = search[1].Split(new string[] { "\" style=\"z" }, StringSplitOptions.None);
                fileUrl = search[0];

                image = Image.FromStream(this.getStream(fileUrl));
                image = (Image)(new Bitmap(image, 224, 93));
                image.Save(imagePath);

                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }
    }
}
